package hydrap2p.proxy.manager;

import hydrap2p.ServiceLocation;

import java.io.IOException;
import java.io.InputStream;

public class NetworkReader {
	private InputStream input;
	
	public NetworkReader(InputStream input)
	{
		this.input=input;
	}
	
	public static final int unserializeInt(byte[] b) {
        return (b[0] << 24)
                + ((b[1] & 0xFF) << 16)
                + ((b[2] & 0xFF) << 8)
                + (b[3] & 0xFF);
	}
	
	public byte peekByte() throws IOException
	{
		byte[] temp=new byte[1];
		input.mark(2);
		int amount=input.read(temp);
		input.reset();
		if (amount==1)
			return temp[0];
		throw new IOException("Failed to read 1 byte");
	}

	public byte readByte() throws IOException
	{
		byte[] temp=new byte[1];
		int amount=input.read(temp);
		if (amount==1)
			return temp[0];
		throw new IOException("Failed to read 1 byte");
	}
	
	public int readInt() throws IOException
	{
		byte[] temp=new byte[4];
		int amount=0;
		int curamount=0;
		while (curamount>=0)
		{
			curamount=input.read(temp, amount, temp.length-amount);
			if (curamount>0)
			{
				amount+=curamount;
				if (amount==temp.length)
					return unserializeInt(temp);
			}
		}
		throw new IOException("Failed to read 4 byte");		
	}
	
	public byte[] readBytes() throws IOException
	{
		int size=readInt();
		byte[] temp=new byte[size];
		int amount=0;
		int curamount=0;
		while (curamount>=0)
		{
			curamount=input.read(temp, amount, temp.length-amount);
			if (curamount>0)
			{
				amount+=curamount;
				if (amount==temp.length)
					return temp;
			}
		}
		throw new IOException("Failed to decode byte array, failure at reading "+amount+"/"+temp.length+" bytes");	
	}
	
	public String readString() throws IOException
	{
		byte[] temp=readBytes();
		return new String(temp,"UTF-8");
	}
	
	public ServiceLocation readServiceLocation() throws IOException
	{
		ServiceLocation ret=new ServiceLocation();
		ret.address=readString();
		ret.port=readInt();
		return ret;
	}
}
